import { Component, OnInit, ElementRef, AfterViewInit } from '@angular/core';
import { LifeSchedule, LifeScheduleService } from 'src/app/service/life-schedule.service';
import { TableStyle, TableStyleService } from 'src/app/service/table-style.service';
import { NzNotificationService } from 'ng-zorro-antd';
import { BreadFieldService } from 'src/app/service/bread-field.service';
import { JsonResult } from 'src/app/model/JsonResult';
import { UUID } from 'angular2-uuid';
import { MessageService } from 'primeng/api';

@Component({
  selector: 'app-life-schedule',
  templateUrl: './life-schedule.component.html',
  styleUrls: ['./life-schedule.component.css']
})
export class LifeScheduleComponent implements OnInit,AfterViewInit {


  vari:{// 变量集合 - 属性集合
    'tableName':string,// 表名称
    'tableData':LifeSchedule[],// 表格组件的数据源
    'tableStyle':TableStyle[],// 列样式表
    'mouseOver_rowIndex':number,// 鼠标悬停的行号
    'emptyRowCount':number, // 空白行数
    'statistics':{ [key:string]:{ label:string,value:number } }, // 有统计的字段的集合
    'searchValue_content':string,
    'visible_filterDropdownMenu':boolean
  } = { 'tableName':'life_schedule','tableData':[],'tableStyle':[],
    mouseOver_rowIndex:-1,'emptyRowCount':1,
    'statistics':{},'searchValue_content':'','visible_filterDropdownMenu':false};
    visible_filterDropdownMenu:boolean = false;

  // 样式表 table_style 在字段 opts 上有值的字段的集合，构建为下拉数据源
  // 格式是：value1=label1,value2=label2...
  // 实例：  1=单程,2=往返
  // 同时实现在表格的对应列上出现下拉数据，将 value 保存到数据源，显示模式下显示 label
  opts_enum:{ [key:string]:{label:string,value:string}[] } = {};

  // 表格编辑用缓存数据
  cache:{
    detail:{ [key:string]:{ edit:boolean,data:LifeSchedule } }
  } = {
    'detail':{}
  }

  mouseOverUUID:string= '';
  filterDropdownMenu:any;

  constructor(
    private pMsgService:MessageService,
    private noti:NzNotificationService,
    private tableStyleService:TableStyleService,
    public detailService:LifeScheduleService,
    public breadField:BreadFieldService,
    private elRef:ElementRef
  ) {
    this.init();
  }

  ngAfterViewInit(): void {
    this.filterDropdownMenu = this.elRef.nativeElement.querySelector('#filterDropdownMenu');
  }

  ngOnInit() {
  }

  init(){
    this.initOpts();
    this.pullTableData();
  }



  // 初始化获取所有带选择数据和字段样式数据
  initOpts(){
    this.tableStyleService.selectByTableName(this.vari.tableName).subscribe(
      ( res:JsonResult ) =>{
        if( res.code !==1 ){
          this.msg(res.msg);
          return
        }

        this.vari.tableStyle = res.data;// 样式字段集合保存到属性中
        this.vari.tableStyle.forEach(ele => {
          if( ele.width_percent>0 )
            ele.width_percent_str = ele.width_percent + 'px';
          this.resolveEnumOpts(ele);// 表 table_style 在字段 opts 上有值的话构建为下拉选择数据
        });
      },error => this.msg('获取表格样式数据时出现异常！')
    )
  }

  // 刷新表格数据 - 从远端获取数据更新本地视图
  pullTableData(){
    this.detailService.refresh().subscribe(
      ( res:JsonResult ) =>{
        if( res.code !== 1 ){
          this.msg(res.msg);
          return
        }

        this.detailService.updateEditCache();// 使用本组件内的属性（表格数据）更新编辑用缓存数据
        // this.updateStatistics();// 更新统计数据
      },error => this.msg('获取表格数据时出现异常！')
    )
  }

  // 构建空白行
  buildEmptyRows(){
    if( this.vari.emptyRowCount === undefined ||this.vari.emptyRowCount === null || this.vari.emptyRowCount<=0 ) return

    let emptyRows:LifeSchedule[] = [];
    let lastUUID:string = '';
    for(let i=0;i<this.vari.emptyRowCount;i++){
      let newRecord = new LifeSchedule();
      lastUUID = newRecord.uuid;
      emptyRows.push(newRecord);
    }

    this.vari.tableData = this.vari.tableData.concat(emptyRows);
    this.detailService.updateEditCache();
    this.detailService.cache.detail[lastUUID].edit = true;
  }


  /**
   * 解析来自数据库端的枚举类型的选项，构建为本地数组
   * @param enums 格式为：value1=label1,value2=label2
   */
  resolveEnumOpts(record:TableStyle){
    let enums = record.opts;
    if( enums === undefined || enums === null || enums.length<=0 ) {
      return
    }
    if( record.immutable === true ) return // 是系统字段则不构建

    let arr = enums.split(',');
    let ret:{label:string,value:string}[] = [];
    arr.forEach(ele => {
      let val = ele.split('=');
      ret.push({ value:String(val[0]),label:val[1] });
    });

    this.opts_enum[record.field_name] = ret;
  }


  // msg(content:string){
  //   this.noti.blank('通知',content);
  // }

  printOpts(){
    console.log(this.opts_enum['one_way']);
  }


  mouseOver(uuid:string){
    // this.mouseOverUUID = uuid;
  }

  mouseLeave(rowIndex:number){
    //this.msg('鼠标走开了 --- ' + rowIndex);
  }

  /**
   * 新增一个空行，并且处于编辑状态
   */
  addEmptyRow(){
    // let record:LifeSchedule = new LifeSchedule();
    // let uuid:string = record.uuid;
    // this.detailService.cache.detail[uuid] = {
    //   edit:true,data:record
    // };

    // this.vari.tableData = this.vari.tableData.concat(record);
    this.detailService.addEmptyRow();
  }

  hasEditableRow():boolean{
    let data = this.detailService.cache.detail;
    if( data === undefined || data === null ) return false;

    for(let attr in this.detailService.cache.detail){
      if( this.detailService.cache.detail[attr].edit )
        return true;
    }

    return false;
  }

  startEdit(rowIndex:number,uuid:string,event){
    event.preventDefault();
    this.detailService.cache.detail[uuid].edit = true;
    // this.fillDefault(rowIndex,uuid);
    // this.msg('开启编辑状态的行是：' + rowIndex + ',' + uuid);
  }

  cancelEdit(rowIndex:number,uuid:string){
    this.detailService.cache.detail[uuid].edit = false;
  }

  saveEdit(rowIndex:number,uuid:string){
    this.detailService.saveEdit(rowIndex,uuid).subscribe(
      ( jr:JsonResult ) =>{
        if( jr.code !==1 ){
          this.msg(jr.msg);
          return
        }

        this.msg('保存完毕！');
      },error => this.msg('保存编辑数据时出现异常！')
    )

  }

  // 删除行 - 仅前端
  deleteRow_front(rowIndex:number,uuid:string){
    // this.vari.tableData = this.vari.tableData.filter(
    //   item => item.uuid !== uuid
    // )
    this.detailService.deleteRow_front(rowIndex);
  }

  /**
   * 删除一行数据：
   * 1. 如果没有iid ，那么只要删除前端 + 更新编辑用缓存数据
   * 2. 删除后端成功后，删除前端 + 更新编辑用缓存数据
   * @param rowIndex 行序号，从0开始
   * @param uuid 行属性uuid
   */
  deleteRow(rowIndex:number,uuid:string){
    let iid = this.detailService.tableData_onGoing[rowIndex].iid;
    if( iid === undefined || iid === null || iid<=0 ){// 仅仅删除前端
      this.deleteRow_front(rowIndex,uuid);
      this.detailService.updateEditCache();
      // this.updateStatistics();
    }else{// 删除后端成功后：删除前端 + 更新编辑用缓存
      this.detailService.deleteByPrimaryKey(iid).subscribe(
        ( res:JsonResult ) => {
          if( res.code != 1 ){
            this.msg(res.msg);
            return
          }

          this.deleteRow_front(rowIndex,uuid);
          this.detailService.updateEditCache();
          // this.updateStatistics();
          this.msg('删除完毕！');
        },error => this.msg('删除时出现异常！')
      )
    }
  }

  cancelDeleteRow(){
    // console.log('取消了删除行');
  }

  setFinished(rowIndex:number,uuid:string){
    this.detailService.tableData_onGoing[rowIndex].finished = 1;
    let data:LifeSchedule = {...this.detailService.tableData_onGoing[rowIndex]};
    this.detailService.update(data).subscribe(
      ( jr:JsonResult ) =>{
        if( jr.code !==1 ){
          this.msg(jr.msg);
          return
        }

        this.detailService.deleteRow_front(rowIndex);
        this.detailService.updateEditCache();
        this.detailService.tableData_finished = this.detailService.tableData_finished.concat(data);
      },error => this.msg('保存数据时出现异常！')
    )
  }


/**
 * 将数据库 table_style 表中设置为枚举类型的下拉选项的字段
 * 显示为其值对应的文本
 * @param record 行数据，单个实体类对象
 * @param fieldName 字段名称
 */
  convertRaw2Show(record:LifeSchedule,tsRow:TableStyle):string{
    return this.breadField.convertRaw2Show(record,tsRow);
  }


  // 从显示模式切换到编辑模式时为下拉框填充数据
  fillDefault(rowIndex:number,uuid:string){
    console.log('进入fillDefault');
    this.vari.tableStyle.forEach(ele => {
      switch(ele.ctl_type){
        case('optsEnum'):
          console.log('是 optsEnum 类型的控件，赋值前：' + this.detailService.cache.detail[uuid].data[ele.field_name]);
          this.detailService.cache.detail[uuid].data[ele.field_name] = this.vari.tableData[rowIndex][ele.field_name];
          console.log('赋值后：' + this.detailService.cache.detail[uuid].data[ele.field_name]);
          break;
        default:
          break;
      }
    });

  }

  setTest(){
    let aa:string = '1+2-3*4/2';
    const gg = /\+|\-|\*|\//g;
    let bb = aa.split(gg);

    console.log(bb);
  }

  // 最初的设计是视图中存在数据表中没有的字段，完全从其他字段通过逻辑或者算数运算得来
  // 后来发现统计上会有问题，放弃该做法，采用较死板的方式：
  // 算数运算中在等于号左边的字段也要在数据表中有字段存储数据，在编辑模式中为不可编辑。
  generateCol(dataRow:LifeSchedule,tsRow:TableStyle){
    return this.breadField.getGeneratedResult(dataRow,tsRow);
  }

  // colHeaderAlign(fieldName:string):string{
  //   let tsRow:TableStyle = this.vari.tableStyle.filter( item => item.field_name === fieldName )[0];
  //   return tsRow.align_header;
  // }

  // colContentAlign(fieldName:string):string{
  //   let tsRow:TableStyle = this.vari.tableStyle.filter( item => item.field_name === fieldName )[0];
  //   return tsRow.align_cell;
  // }

  // 更新统计数据
  updateStatistics(){
    if( this.vari.tableData.length<=0 ) return

    this.vari.statistics = null;
    this.vari.statistics = {};

    // 遍历字段构建汇总对象
    let arr = this.vari.tableStyle.filter(item=>item.statistics);
    if( arr.length<=0 ) return;
    arr.forEach(ele => {
      this.vari.statistics[ele.field_name] = { value:0,label:'' };
    });


    this.vari.tableData.forEach(ele => {
      this.vari.tableStyle.forEach(ele1 => {
        let field:string = ele1.field_name;
        if( ele1.statistics ){
          let curValue:number = ele[field] === undefined?0:ele[field];
          curValue = curValue === null?0:curValue;
          this.vari.statistics[field].value = this.vari.statistics[field].value + curValue;
          this.vari.statistics[field].label = Number(this.vari.statistics[field].value).toFixed(1);
        }
      });
    });
  }


  refreshTable(){
    this.detailService.refresh().subscribe(
      ( jr:JsonResult ) => {
        if( jr.code !==1 ){
          this.msg(jr.msg);
          return
        }

        this.msg('刷新完毕！');
      },error => this.msg('刷新表格数据时出现异常！')
    )
  }


  resolveFormula(dataRow:LifeSchedule,tsRow:TableStyle):string{
    if( !tsRow.statistics ) return

    return this.breadField.useFormatter(dataRow,tsRow)
  }

  // 编辑状态下，编辑文本变动则对应修改其相关公式关联的字段的值
  inputChange(dataRow:LifeSchedule,tsRow:TableStyle){
    let arr:{ fieldName:string,value:number }[] = this.breadField.triggerFormula(dataRow,tsRow,this.vari.tableStyle);
    if( arr === undefined || arr === null || arr.length<=0 ) return
    arr.forEach(ele => {
      this.detailService.cache.detail[dataRow.uuid].data[ele.fieldName] = ele.value;
    });
  }

  // 将已经完成的日程返回为进行中
  turn2Ing(rowIndex:number,uuid:string){
    this.detailService.turn2Ing(rowIndex,uuid).subscribe(
      ( jr:JsonResult ) =>{
        if( jr.code !==1 ) {
          this.msg(jr.msg);
          return
        }

      },error => this.msg('恢复为进行中时出现异常！')
    )
  }

  searchContent(){
    this.detailService.filterContent(this.vari.searchValue_content);
    // this.filterDropdownMenu.nzVisible = false;
    this.visible_filterDropdownMenu = false;
  }

  resetFilterContent(){
    this.vari.searchValue_content = '';
    this.detailService.filterContent(this.vari.searchValue_content);
    this.visible_filterDropdownMenu = false;
  }


  //#region 自定义彩色消息通知
  msg(content:string) {
    this.pMsgService.add({key: 'custom', severity:'info', summary: '通知', detail:content});
  }
  //#endregion

  //#region 事件 - 单击数据行
  onClick_dataRow(rowIndex: number, uuid: any) {
    this.detailService.setSelectedRow(rowIndex,uuid);
  }
  //#endregion

  //#region 更新排序序号
  updateSeq(){
    this.detailService.updateSeq().subscribe(
      ( jr:JsonResult ) =>{
        if( jr.code !==1 ){
          this.msg(jr.msg);
          return
        }

        this.msg('更新排序序号成功！');
      },error => this.msg('更新排序序号时出现异常！')
    )
  }
  //#endregion

}


